package com.kujie.access.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kujie.access.domain.po.AccessContractPaymentRecord;
import com.kujie.access.domain.query.PayManageQuery;
import com.kujie.access.domain.vo.PayManageVo;
import com.kujie.access.mapper.AccessContractPaymentRecordMapper;
import com.kujie.access.service.IAccessContractPaymentRecordService;
import com.kujie.access.service.IPayService;
import com.kujie.common.core.utils.StringUtils;
import com.kujie.common.excel.core.ExcelResult;
import com.kujie.common.excel.utils.ExcelUtil;
import com.kujie.common.mybatis.core.page.PageQuery;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 缴费管理 api
 *
 * @author jyy
 * @date 2025-05-26
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PayServiceImpl implements IPayService {

    private final AccessContractPaymentRecordMapper paymentRecordMapper;
    private final IAccessContractPaymentRecordService paymentRecordService;

    /**
     * 获取缴费管理分页
     *
     * @param query     入参
     * @param pageQuery 分页入参
     * @return Page<PayManageVo>
     */
    @Override
    public Page<PayManageVo> getPayManagePage(PayManageQuery query, PageQuery pageQuery) {
        Page<PayManageVo> result = pageQuery.build(new PayManageVo());

        LambdaQueryWrapper<AccessContractPaymentRecord> lqw = getAccessContractPaymentRecordLambdaQueryWrapper(query);
        Page<AccessContractPaymentRecord> page = paymentRecordMapper.selectPage(pageQuery.build(), lqw);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return result;
        }

        List<PayManageVo> voList = page.getRecords().stream().map(item -> {
            PayManageVo vo = new PayManageVo();
            vo.setId(item.getId());
            vo.setContractUuid(item.getContractUuid());
            vo.setContractName(item.getContractName());
            vo.setPaymentAmount(item.getPaymentAmount());
            vo.setPaymentType(item.getPaymentType());
            vo.setPaymentLeaseTerm(item.getPaymentLeaseTerm());
            vo.setPaymentDeadline(item.getPaymentDeadline());
            return vo;
        }).toList();

        result.setRecords(voList);
        result.setTotal(page.getTotal());
        return result;
    }

    /**
     * 新增缴费管理
     *
     * @param query   入参
     * @param isValid 是否校验数据
     * @return int
     */
    @Override
    public int addPayManage(PayManageQuery query, boolean isValid) {
        AccessContractPaymentRecord po = BeanUtil.toBean(query, AccessContractPaymentRecord.class);
        return paymentRecordMapper.insert(po);
    }

    /**
     * 修改缴费管理
     *
     * @param query   入参
     * @param isValid 是否校验数据
     * @return int
     */
    @Override
    public int updatePayManage(PayManageQuery query, boolean isValid) {
        AccessContractPaymentRecord po = BeanUtil.toBean(query, AccessContractPaymentRecord.class);
        return paymentRecordMapper.updateById(po);
    }

    /**
     * 修改缴费管理
     *
     * @param ids     入参
     * @param isValid 是否校验数据
     * @return int
     */
    @Override
    public int deletePayManage(List<Long> ids, boolean isValid) {
        if (ids == null) {
            return 0;
        }

        return paymentRecordMapper.deleteByIds(ids);
    }

    /**
     * 获取缴费管理列表
     *
     * @param query 入参
     * @return List<PayManageVo>
     */
    @Override
    public List<PayManageVo> getPayManageList(PayManageQuery query) {
        List<AccessContractPaymentRecord> poList;
        if (!query.getIsAll()) {
            poList = paymentRecordMapper.selectByIds(query.getIds());
        } else {
            LambdaQueryWrapper<AccessContractPaymentRecord> lqw = getAccessContractPaymentRecordLambdaQueryWrapper(query);
            poList = paymentRecordMapper.selectList(lqw);
        }

        return poList.stream().map(item -> {
            PayManageVo vo = new PayManageVo();
            vo.setId(item.getId());
            vo.setContractUuid(item.getContractUuid());
            vo.setContractName(item.getContractName());
            vo.setPaymentAmount(item.getPaymentAmount());
            vo.setPaymentType(item.getPaymentType());
            vo.setPaymentLeaseTerm(item.getPaymentLeaseTerm());
            vo.setPaymentDeadline(item.getPaymentDeadline());
            vo.setRemark(item.getRemark());
            return vo;
        }).toList();
    }

    /**
     * 导入缴费管理模板
     *
     * @param file 文件流
     * @return String
     */
    @Override
    public String importPayManage(MultipartFile file) {
        // 导入数据
        List<PayManageVo> dtoList = new ArrayList<>();
        try {
            // 解析文件数据数据
            ExcelResult<PayManageVo> result = ExcelUtil.importExcel(file.getInputStream(), PayManageVo.class, true);
            // 获取数据
            dtoList = result.getList();
        } catch (IOException e) {
            log.error(e.toString());
        }
        if (CollectionUtils.isEmpty(dtoList)) {
            log.error("导入数据为空");
            return "";
        }

        // 查询数据
        Map<String, AccessContractPaymentRecord> poMap = new HashMap<>();
        List<AccessContractPaymentRecord> poList = paymentRecordMapper.selectList(new QueryWrapper<>());
        if (!CollectionUtils.isEmpty(poList)) {
            poMap = poList.stream().collect(Collectors.toMap(AccessContractPaymentRecord::getContractUuid, po -> po));
        }

        // 新增数据
        List<AccessContractPaymentRecord> insertList = new ArrayList<>();
        // 更新数据
        List<AccessContractPaymentRecord> updateList = new ArrayList<>();

        // 数据处理
        for (PayManageVo dto : dtoList) {
            AccessContractPaymentRecord po = poMap.get(dto.getContractUuid());
            if (null == po) {
                // 新增
                po = new AccessContractPaymentRecord();
                BeanUtils.copyProperties(dto, po);
                po.setCreateBy(1L);
                po.setCreateTime(new Date());
                insertList.add(po);
            } else {
                po.setContractName(dto.getContractName());
                po.setPaymentAmount(dto.getPaymentAmount());
                po.setPaymentType(dto.getPaymentType());
                po.setPaymentLeaseTerm(dto.getPaymentLeaseTerm());
                po.setPaymentDeadline(dto.getPaymentDeadline());
                po.setRemark(dto.getRemark());
                po.setUpdateBy(1L);
                po.setUpdateTime(new Date());
                updateList.add(po);
            }
        }

        if (!CollectionUtils.isEmpty(insertList)) {
            paymentRecordService.saveBatch(insertList);
        }

        if (!CollectionUtils.isEmpty(updateList)) {
            paymentRecordService.updateBatchById(updateList);
        }
        return String.format("新增：%d条，修改：%d条", insertList.size(), updateList.size());
    }

    @Override
    public PayManageVo detail(Long id) {
        AccessContractPaymentRecord accessContractPaymentRecord = paymentRecordMapper.selectById(id);
        PayManageVo payManageVo = new PayManageVo();
        BeanUtils.copyProperties(accessContractPaymentRecord, payManageVo);
        return payManageVo;
    }

    private static LambdaQueryWrapper<AccessContractPaymentRecord> getAccessContractPaymentRecordLambdaQueryWrapper(PayManageQuery query) {
        LambdaQueryWrapper<AccessContractPaymentRecord> lqw = new LambdaQueryWrapper<>();
        lqw.like(StringUtils.isNotEmpty(query.getContractUuid()), AccessContractPaymentRecord::getContractUuid, query.getContractUuid());
        lqw.like(StringUtils.isNotEmpty(query.getContractName()), AccessContractPaymentRecord::getContractName, query.getContractName());
        lqw.eq(StringUtils.isNotEmpty(query.getPaymentType()), AccessContractPaymentRecord::getPaymentType, query.getPaymentType());
        if (StringUtils.isNotEmpty(query.getPayStartTime()) && StringUtils.isNotEmpty(query.getPayEndTime())) {
            lqw.ge(AccessContractPaymentRecord::getPaymentDeadline, query.getPayStartTime())
                .le(AccessContractPaymentRecord::getPaymentDeadline, query.getPayEndTime());
        }
        return lqw;
    }

}
